#include "gateway.hpp"
#include "scence.hpp"

#include "scence_mgr.hpp"

IMPL_LOGGER(ScenceMgr, logger);

ScenceMgr::ScenceMgr()
{
}

ScenceMgr::~ScenceMgr()
{
}

void ScenceMgr::del_scence(Connection & conn)
{
	Scence * scence = find_scence(conn);

	if (NULL == scence)
	{
		LOG4CPLUS_ERROR(logger, "not found scence. connid: " << conn.conn_id().to_string());
		return;
	}

	_svrid_map.erase(scence->_svr_id);

	Scence::RoomMap_Iter iter = scence->_room_map.begin();
	for (; iter != scence->_room_map.end(); ++ iter)
	{
		_position_map.erase(position(scence->_area_id, iter->first));
	}
}

Scence * ScenceMgr::find_scence(Connection & conn)
{
	ScenceMap_Iter iter = _svrid_map.begin();
	for (; iter != _svrid_map.end(); ++ iter)
	{
		Scence * scence = iter->second;
		if (scence->_conn == &conn)
		{
			return scence;
		}
	}
	return NULL;
}

Scence * ScenceMgr::find_scence(SVRID svrid)
{
	ScenceMap_Iter iter = _svrid_map.find((uint32_t)svrid);
	return ((iter == _svrid_map.end())? NULL: iter->second);
}

Scence * ScenceMgr::find_scence(AREAID area_id, ROOMID room_id)
{
	ScenceMap_Iter iter = _position_map.find(position(area_id, room_id));

	return ((_position_map.end() == iter)? NULL: iter->second);
}

template <>
int ScenceMgr::handle(Connection & conn, const SSReportAreaReq & req)
{
	Scence * scence = new Scence(conn, req);

	assert(NULL != scence);

	assert(_svrid_map.insert(std::make_pair((uint32_t)req._svr_id, scence)).second);

	std::vector<ROOMID>::const_iterator iter = req._room_list.begin();
	for (; iter != req._room_list.end(); ++ iter)
	{
		uint32_t p = position(req._area_id, *iter);

		assert(_position_map.insert(std::make_pair(p, scence)).second);
	}
	
	return 0;
}

template <>
int ScenceMgr::handle(Connection & conn, const CSGetRoomReq & req)
{
	SCGetRoomRes res;
	
	res._area_id  = req._area_id;

	ScenceMap_Iter iter = _svrid_map.begin();
	for (; iter != _svrid_map.end(); ++ iter)
	{
		if (iter->second->_area_id == req._area_id)
		{
			iter->second->fill_room_b(res._room_list);
		}
	}

	Gateway::instance().reactor()->send_data(conn, (void*)&res);

	return 0;
}

